package com.mojian.controller.membership;

import com.mojian.common.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.dev33.satoken.stp.StpUtil;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 会员套餐控制器
 */
@RestController
@RequestMapping("/protal/membership")
@RequiredArgsConstructor
@Api(tags = "会员套餐接口")
@Slf4j
public class MembershipController {

    private final JdbcTemplate jdbcTemplate;

    /**
     * 获取会员套餐列表
     */
    @GetMapping("/plans")
    @ApiOperation("获取会员套餐列表")
    public Result<List<Map<String, Object>>> getMembershipPlans() {
        try {
            // 使用JdbcTemplate直接查询会员套餐表
            String sql = "SELECT id, name, price, original_price as originalPrice, " +
                         "days, unit, discount, create_time as createTime " +
                         "FROM member_plan ORDER BY price ASC";
            List<Map<String, Object>> plans = jdbcTemplate.queryForList(sql);
            
            log.info("查询到{}个会员套餐", plans.size());
            
            // 如果没有套餐数据，初始化默认套餐
            if (plans.isEmpty()) {
                initializeTestData();
                plans = jdbcTemplate.queryForList(sql);
                log.info("已初始化默认会员套餐，现在有{}个套餐", plans.size());
            }
            
            return Result.success(plans);
        } catch (Exception e) {
            log.error("获取会员套餐失败", e);
            return Result.error("获取会员套餐失败: " + e.getMessage());
        }
    }
    
    /**
     * 创建会员订单
     */
    @PostMapping("/order/create")
    @ApiOperation("创建会员订单")
    public Result<Map<String, Object>> createMemberOrder(@RequestBody Map<String, Object> orderRequest) {
        log.info("创建会员订单: {}", orderRequest);
        try {
            // 获取当前登录用户ID
            Long userId = StpUtil.getLoginIdAsLong();
            Integer planId = Integer.valueOf(orderRequest.get("planId").toString());
            String paymentMethod = (String) orderRequest.get("paymentMethod");
            
            // 验证套餐是否存在
            String planSql = "SELECT * FROM member_plan WHERE id = ?";
            List<Map<String, Object>> plans = jdbcTemplate.queryForList(planSql, planId);
            if (plans.isEmpty()) {
                return Result.error("套餐不存在");
            }
            
            Map<String, Object> plan = plans.get(0);
            BigDecimal price = (BigDecimal) plan.get("price");
            Integer days = (Integer) plan.get("days");
            
            // 生成订单号
            String orderNo = generateOrderNo();
            
            // 创建订单
            String insertSql = "INSERT INTO member_order (order_no, user_id, plan_id, days, payment_method, " +
                              "amount, status, create_time, update_time) " +
                              "VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
            
            jdbcTemplate.update(insertSql, orderNo, userId, planId, days, paymentMethod, price, "PENDING");
            
            // 构建响应结果
            Map<String, Object> result = new HashMap<>();
            result.put("orderNo", orderNo);
            result.put("planId", planId);
            result.put("planName", plan.get("name"));
            result.put("days", days);
            result.put("amount", price);
            result.put("paymentMethod", paymentMethod);
            result.put("status", "PENDING");
            
            // 模拟生成支付二维码URL
            String qrCodeUrl = "https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=" + orderNo;
            result.put("qrCodeUrl", qrCodeUrl);
            
            return Result.success(result);
        } catch (Exception e) {
            log.error("创建会员订单失败", e);
            return Result.error("创建会员订单失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询订单状态
     */
    @GetMapping("/order/status")
    @ApiOperation("查询订单状态")
    public Result<Map<String, Object>> checkOrderStatus(@RequestParam String orderNo) {
        log.info("查询订单状态: {}", orderNo);
        try {
            // 查询订单信息
            String sql = "SELECT mo.*, mp.name as planName " +
                         "FROM member_order mo " +
                         "LEFT JOIN member_plan mp ON mo.plan_id = mp.id " +
                         "WHERE mo.order_no = ?";
            List<Map<String, Object>> orders = jdbcTemplate.queryForList(sql, orderNo);
            
            if (orders.isEmpty()) {
                return Result.error("订单不存在");
            }
            
            Map<String, Object> order = orders.get(0);
            
            // 处理日期时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            if (order.get("create_time") != null) {
                LocalDateTime createTime = ((java.sql.Timestamp) order.get("create_time")).toLocalDateTime();
                order.put("createTime", createTime.format(formatter));
            }
            
            if (order.get("pay_time") != null) {
                LocalDateTime payTime = ((java.sql.Timestamp) order.get("pay_time")).toLocalDateTime();
                order.put("payTime", payTime.format(formatter));
            }
            
            // 如果订单状态是SUCCESS，更新会员信息
            if ("SUCCESS".equals(order.get("status")) && !isUserMembershipUpdated(orderNo)) {
                updateUserMembership((Long) order.get("user_id"), (Integer) order.get("days"));
                markOrderProcessed(orderNo);
            }
            
            return Result.success(order);
        } catch (Exception e) {
            log.error("查询订单状态失败", e);
            return Result.error("查询订单状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 模拟支付成功
     */
    @PostMapping("/order/pay/simulate")
    @ApiOperation("模拟支付成功（仅用于测试）")
    public Result<Map<String, Object>> simulatePayment(@RequestBody Map<String, Object> request) {
        String orderNo = (String) request.get("orderNo");
        log.info("模拟支付成功: {}", orderNo);
        
        try {
            // 更新订单状态为支付成功
            String sql = "UPDATE member_order SET status = 'SUCCESS', pay_time = NOW(), " +
                         "trade_no = ?, update_time = NOW() " +
                         "WHERE order_no = ? AND status = 'PENDING'";
            
            // 生成模拟的交易号
            String tradeNo = "2025" + System.currentTimeMillis() + new Random().nextInt(10000);
            
            int updated = jdbcTemplate.update(sql, tradeNo, orderNo);
            
            if (updated > 0) {
                // 查询订单信息
                String orderSql = "SELECT mo.*, mp.name as planName " +
                                 "FROM member_order mo " +
                                 "LEFT JOIN member_plan mp ON mo.plan_id = mp.id " +
                                 "WHERE mo.order_no = ?";
                List<Map<String, Object>> orders = jdbcTemplate.queryForList(orderSql, orderNo);
                
                if (!orders.isEmpty()) {
                    Map<String, Object> order = orders.get(0);
                    
                    // 更新用户会员信息
                    updateUserMembership((Long) order.get("user_id"), (Integer) order.get("days"));
                    markOrderProcessed(orderNo);
                    
                    return Result.success(order);
                }
            }
            
            return Result.error("支付失败，订单不存在或已支付");
        } catch (Exception e) {
            log.error("模拟支付失败", e);
            return Result.error("模拟支付失败: " + e.getMessage());
        }
    }
    
    /**
     * 初始化测试数据
     */
    @PostMapping("/init-test-data")
    @ApiOperation("初始化测试数据（仅用于测试）")
    public Result<Map<String, Object>> initializeTestDataEndpoint() {
        try {
            Map<String, Object> result = initializeTestData();
            return Result.success(result);
        } catch (Exception e) {
            log.error("初始化测试数据失败", e);
            return Result.error("初始化测试数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        // 格式：VIP + 年月日时分秒 + 4位随机数
        LocalDateTime now = LocalDateTime.now();
        String timeStr = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        
        // 生成4位随机数
        Random random = new Random();
        int randomNum = random.nextInt(10000);
        String randomStr = String.format("%04d", randomNum);
        
        return "VIP" + timeStr + randomStr;
    }
    
    /**
     * 检查用户会员信息是否已更新
     */
    private boolean isUserMembershipUpdated(String orderNo) {
        String sql = "SELECT COUNT(*) FROM member_order WHERE order_no = ? AND status = 'SUCCESS' AND user_id IN " +
                    "(SELECT user_id FROM member_user)";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class, orderNo);
        return count != null && count > 0;
    }
    
    /**
     * 标记订单已处理
     */
    private void markOrderProcessed(String orderNo) {
        // 实际项目中可以添加一个标记字段，这里简化处理
        log.info("订单已处理: {}", orderNo);
    }
    
    /**
     * 更新用户会员信息
     */
    private void updateUserMembership(Long userId, Integer days) {
        try {
            // 查询用户是否已是会员
            String checkSql = "SELECT * FROM member_user WHERE user_id = ?";
            List<Map<String, Object>> members = jdbcTemplate.queryForList(checkSql, userId);
            
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime expireTime;
            
            if (members.isEmpty()) {
                // 新增会员记录
                expireTime = now.plusDays(days);
                String insertSql = "INSERT INTO member_user (user_id, level, expire_time, create_time, update_time) " +
                                  "VALUES (?, ?, ?, NOW(), NOW())";
                jdbcTemplate.update(insertSql, userId, 1, expireTime);
                log.info("新增会员: userId={}, expireTime={}", userId, expireTime);
            } else {
                // 更新现有会员记录
                Map<String, Object> member = members.get(0);
                java.sql.Timestamp currentExpireTime = (java.sql.Timestamp) member.get("expire_time");
                
                // 如果当前过期时间在现在之后，则在当前过期时间基础上增加天数
                // 否则，从现在开始计算新的过期时间
                if (currentExpireTime != null && currentExpireTime.after(new java.sql.Timestamp(System.currentTimeMillis()))) {
                    expireTime = currentExpireTime.toLocalDateTime().plusDays(days);
                } else {
                    expireTime = now.plusDays(days);
                }
                
                String updateSql = "UPDATE member_user SET expire_time = ?, update_time = NOW() WHERE user_id = ?";
                jdbcTemplate.update(updateSql, expireTime, userId);
                log.info("更新会员: userId={}, expireTime={}", userId, expireTime);
            }
        } catch (Exception e) {
            log.error("更新用户会员信息失败", e);
            throw e;
        }
    }
    
    /**
     * 初始化测试数据
     */
    private Map<String, Object> initializeTestData() {
        log.info("初始化会员相关测试数据");
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 1. 检查并创建会员套餐
            String countPlanSql = "SELECT COUNT(*) FROM member_plan";
            Integer planCount = jdbcTemplate.queryForObject(countPlanSql, Integer.class);
            
            if (planCount == null || planCount == 0) {
                log.info("会员套餐表为空，创建默认套餐");
                
                // 创建月度套餐
                String insertMonthSql = "INSERT INTO member_plan (name, price, original_price, days, unit, discount, create_time, update_time) " +
                                      "VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())";
                jdbcTemplate.update(insertMonthSql, "月度会员", new BigDecimal("30.00"), null, 30, "月", null);
                
                // 创建季度套餐
                String insertQuarterSql = "INSERT INTO member_plan (name, price, original_price, days, unit, discount, create_time, update_time) " +
                                        "VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())";
                jdbcTemplate.update(insertQuarterSql, "季度会员", new BigDecimal("78.00"), new BigDecimal("90.00"), 90, "季", 8.7);
                
                // 创建年度套餐
                String insertYearSql = "INSERT INTO member_plan (name, price, original_price, days, unit, discount, create_time, update_time) " +
                                     "VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())";
                jdbcTemplate.update(insertYearSql, "年度会员", new BigDecimal("258.00"), new BigDecimal("360.00"), 365, "年", 7.2);
                
                result.put("planInitialized", true);
            } else {
                result.put("planInitialized", false);
                result.put("planCount", planCount);
            }
            
            return result;
        } catch (Exception e) {
            log.error("初始化测试数据失败", e);
            result.put("error", e.getMessage());
            return result;
        }
    }
} 